use crate::src::src::compare_int::{int_compare, int_equal};
use crate::src::src::compare_pointer::{pointer_compare, pointer_equal};
use crate::src::src::compare_string::{
    string_compare, string_equal, string_nocase_compare, string_nocase_equal,
};
use crate::src::struct_and_type::UnitTestFunction;
use crate::src::test::framework::run_tests;

#[no_mangle]
pub extern "C" fn test_int_compare() {
    let mut a: i32 = 4;
    let mut b: i32 = 8;
    let mut c: i32 = 4;
    assert!(
        int_compare(
            &mut a as *mut i32 as *mut (),
            &mut b as *mut i32 as *mut (),
        ) < 0
    );
    assert!(
        int_compare(
            &mut b as *mut i32 as *mut (),
            &mut a as *mut i32 as *mut (),
        ) > 0
    );
    assert!(
        int_compare(
            &mut a as *mut i32 as *mut (),
            &mut c as *mut i32 as *mut (),
        ) == 0
    );
}
#[no_mangle]
pub extern "C" fn test_int_equal() {
    let mut a: i32 = 4;
    let mut b: i32 = 8;
    let mut c: i32 = 4;
    assert!(
        int_equal(
            &mut a as *mut i32 as *mut (),
            &mut c as *mut i32 as *mut (),
        ) != 0
    );
    assert!(
        int_equal(
            &mut a as *mut i32 as *mut (),
            &mut b as *mut i32 as *mut (),
        ) == 0
    );
}
#[no_mangle]
pub extern "C" fn test_pointer_compare() {
    let mut array: [i32; 5] = [0; 5];
    assert!(
        pointer_compare(
            (unsafe { &mut *array.as_mut_ptr().offset(0 as i32 as isize) }) as *mut i32
                as *mut (),
            (unsafe { &mut *array.as_mut_ptr().offset(4 as i32 as isize) }) as *mut i32
                as *mut (),
        ) < 0
    );
    assert!(
        pointer_compare(
            (unsafe { &mut *array.as_mut_ptr().offset(3 as i32 as isize) }) as *mut i32
                as *mut (),
            (unsafe { &mut *array.as_mut_ptr().offset(2 as i32 as isize) }) as *mut i32
                as *mut (),
        ) > 0
    );
    assert!(
        pointer_compare(
            (unsafe { &mut *array.as_mut_ptr().offset(4 as i32 as isize) }) as *mut i32
                as *mut (),
            (unsafe { &mut *array.as_mut_ptr().offset(4 as i32 as isize) }) as *mut i32
                as *mut (),
        ) == 0
    );
}
#[no_mangle]
pub extern "C" fn test_pointer_equal() {
    let mut a: i32 = 0;
    let mut b: i32 = 0;
    assert!(
        pointer_equal(
            &mut a as *mut i32 as *mut (),
            &mut a as *mut i32 as *mut (),
        ) != 0
    );
    assert!(
        pointer_equal(
            &mut a as *mut i32 as *mut (),
            &mut b as *mut i32 as *mut (),
        ) == 0
    );
}
#[no_mangle]
pub extern "C" fn test_string_compare() {
    let mut test1: [i8; 6] =
        *(unsafe { ::core::mem::transmute::<&[u8; 6], &mut [i8; 6]>(b"Apple\0") });
    let mut test2: [i8; 7] =
        *(unsafe { ::core::mem::transmute::<&[u8; 7], &mut [i8; 7]>(b"Orange\0") });
    let mut test3: [i8; 6] =
        *(unsafe { ::core::mem::transmute::<&[u8; 6], &mut [i8; 6]>(b"Apple\0") });
    assert!(
        string_compare(
            test1.as_mut_ptr() as *mut (),
            test2.as_mut_ptr() as *mut (),
        ) < 0
    );
    assert!(
        string_compare(
            test2.as_mut_ptr() as *mut (),
            test1.as_mut_ptr() as *mut (),
        ) > 0
    );
    assert!(
        string_compare(
            test1.as_mut_ptr() as *mut (),
            test3.as_mut_ptr() as *mut (),
        ) == 0
    );
}
#[no_mangle]
pub extern "C" fn test_string_equal() {
    let mut test1: [i8; 22] = *(unsafe {
        ::core::mem::transmute::<&[u8; 22], &mut [i8; 22]>(b"this is a test string\0")
    });
    let mut test2: [i8; 23] = *(unsafe {
        ::core::mem::transmute::<&[u8; 23], &mut [i8; 23]>(b"this is a test string \0")
    });
    let mut test3: [i8; 21] =
        *(unsafe { ::core::mem::transmute::<&[u8; 21], &mut [i8; 21]>(b"this is a test strin\0") });
    let mut test4: [i8; 22] = *(unsafe {
        ::core::mem::transmute::<&[u8; 22], &mut [i8; 22]>(b"this is a test strinG\0")
    });
    let mut test5: [i8; 22] = *(unsafe {
        ::core::mem::transmute::<&[u8; 22], &mut [i8; 22]>(b"this is a test string\0")
    });
    assert!(
        string_equal(
            test1.as_mut_ptr() as *mut (),
            test5.as_mut_ptr() as *mut (),
        ) != 0
    );
    assert!(
        string_equal(
            test1.as_mut_ptr() as *mut (),
            test2.as_mut_ptr() as *mut (),
        ) == 0
    );
    assert!(
        string_equal(
            test1.as_mut_ptr() as *mut (),
            test3.as_mut_ptr() as *mut (),
        ) == 0
    );
    assert!(
        string_equal(
            test1.as_mut_ptr() as *mut (),
            test4.as_mut_ptr() as *mut (),
        ) == 0
    );
}
#[no_mangle]
pub extern "C" fn test_string_nocase_compare() {
    let mut test1: [i8; 6] =
        *(unsafe { ::core::mem::transmute::<&[u8; 6], &mut [i8; 6]>(b"Apple\0") });
    let mut test2: [i8; 7] =
        *(unsafe { ::core::mem::transmute::<&[u8; 7], &mut [i8; 7]>(b"Orange\0") });
    let mut test3: [i8; 6] =
        *(unsafe { ::core::mem::transmute::<&[u8; 6], &mut [i8; 6]>(b"Apple\0") });
    let mut test4: [i8; 6] =
        *(unsafe { ::core::mem::transmute::<&[u8; 6], &mut [i8; 6]>(b"Alpha\0") });
    let mut test5: [i8; 6] =
        *(unsafe { ::core::mem::transmute::<&[u8; 6], &mut [i8; 6]>(b"bravo\0") });
    let mut test6: [i8; 8] =
        *(unsafe { ::core::mem::transmute::<&[u8; 8], &mut [i8; 8]>(b"Charlie\0") });
    assert!(
        string_nocase_compare(
            test1.as_mut_ptr() as *mut (),
            test2.as_mut_ptr() as *mut (),
        ) < 0
    );
    assert!(
        string_nocase_compare(
            test2.as_mut_ptr() as *mut (),
            test1.as_mut_ptr() as *mut (),
        ) > 0
    );
    assert!(
        string_nocase_compare(
            test1.as_mut_ptr() as *mut (),
            test3.as_mut_ptr() as *mut (),
        ) == 0
    );
    assert!(
        string_nocase_compare(
            test4.as_mut_ptr() as *mut (),
            test5.as_mut_ptr() as *mut (),
        ) < 0
    );
    assert!(
        string_nocase_compare(
            test5.as_mut_ptr() as *mut (),
            test6.as_mut_ptr() as *mut (),
        ) < 0
    );
}
#[no_mangle]
pub extern "C" fn test_string_nocase_equal() {
    let mut test1: [i8; 22] = *(unsafe {
        ::core::mem::transmute::<&[u8; 22], &mut [i8; 22]>(b"this is a test string\0")
    });
    let mut test2: [i8; 23] = *(unsafe {
        ::core::mem::transmute::<&[u8; 23], &mut [i8; 23]>(b"this is a test string \0")
    });
    let mut test3: [i8; 21] =
        *(unsafe { ::core::mem::transmute::<&[u8; 21], &mut [i8; 21]>(b"this is a test strin\0") });
    let mut test4: [i8; 22] = *(unsafe {
        ::core::mem::transmute::<&[u8; 22], &mut [i8; 22]>(b"this is a test strinG\0")
    });
    let mut test5: [i8; 22] = *(unsafe {
        ::core::mem::transmute::<&[u8; 22], &mut [i8; 22]>(b"this is a test string\0")
    });
    assert!(
        string_nocase_equal(
            test1.as_mut_ptr() as *mut (),
            test5.as_mut_ptr() as *mut (),
        ) != 0
    );
    assert!(
        string_nocase_equal(
            test1.as_mut_ptr() as *mut (),
            test2.as_mut_ptr() as *mut (),
        ) == 0
    );
    assert!(
        string_nocase_equal(
            test1.as_mut_ptr() as *mut (),
            test3.as_mut_ptr() as *mut (),
        ) == 0
    );
    assert!(
        string_nocase_equal(
            test1.as_mut_ptr() as *mut (),
            test4.as_mut_ptr() as *mut (),
        ) != 0
    );
}
static mut tests_test_compare_functions: [UnitTestFunction; 9] = {
    [
        Some(test_int_compare as unsafe extern "C" fn() -> ()),
        Some(test_int_equal as unsafe extern "C" fn() -> ()),
        Some(test_pointer_compare as unsafe extern "C" fn() -> ()),
        Some(test_pointer_equal as unsafe extern "C" fn() -> ()),
        Some(test_string_compare as unsafe extern "C" fn() -> ()),
        Some(test_string_equal as unsafe extern "C" fn() -> ()),
        Some(test_string_nocase_compare as unsafe extern "C" fn() -> ()),
        Some(test_string_nocase_equal as unsafe extern "C" fn() -> ()),
        None,
    ]
};
fn main_0_test_compare_functions(mut _argc: i32, mut _argv: *mut *mut i8) -> i32 {
    run_tests(unsafe { tests_test_compare_functions.as_mut_ptr() });
    return 0;
}
pub fn main_test_compare_functions() {
    let mut args: Vec<*mut i8> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::core::ptr::null_mut());
    {
        ::std::process::exit(main_0_test_compare_functions(
            (args.len() - 1) as i32,
            args.as_mut_ptr() as *mut *mut i8,
        ) as i32)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn entry_for_test_int_compare() {
        test_int_compare();
    }
    #[test]
    fn entry_for_test_int_equal() {
        test_int_equal();
    }
    #[test]
    fn entry_for_test_pointer_compare() {
        test_pointer_compare();
    }
    #[test]
    fn entry_for_test_pointer_equal() {
        test_pointer_equal();
    }
    #[test]
    fn entry_for_test_string_compare() {
        test_string_compare();
    }
    #[test]
    fn entry_for_test_string_equal() {
        test_string_equal();
    }
    #[test]
    fn entry_for_test_string_nocase_compare() {
        test_string_nocase_compare();
    }
    #[test]
    fn entry_for_test_string_nocase_equal() {
        test_string_nocase_equal();
    }
}